/*
    Estado        Metodo
    P           eliminarUsuario() - Diego
    ?P?         existeUsuarioPorNombreusuario() - Mauri - Diego
    P           modificarUsuario() - Diego
    P           insertarUsuario() - Diego
    P           listarUsuarios() - Diego
    P           obtenerUsuario() - Diego
    P           obtenerUsuarioPorNombreUsuario() - Diego
 */

package dal;

import static java.lang.System.*;

import bd.BoundParam;
import bd.ConexionAvw;

import static java.sql.Types.*;
        

import excepciones.AvwException;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.sql.Statement;

import java.util.ArrayList;

import java.util.logging.Level;
import java.util.logging.Logger;

import negocio.ArticuloWeb;
import negocio.UsuarioWeb;

import util.Utiles;

public class UsuarioDAL {
    static final Logger logger = Utiles.iniciarLogger("UsuarioDAL",false);
    
    /**
     * Obtiene todos los usuarios existentes en el sistema.
     * @return ArrayList de objetos UsuarioWeb del sistema. 
     */
    public static ArrayList<UsuarioWeb> listarUsuarios() throws AvwException {
        ArrayList<UsuarioWeb> usuarios = new ArrayList<UsuarioWeb>();
        StringBuilder sql = new StringBuilder();
        ResultSet rs;
        ConexionAvw conexion = new ConexionAvw();
        sql.append("SELECT ");
        sql.append("usw_codigo, ");
        sql.append("usw_nombre, ");
        sql.append("usw_nombre_usuario, ");
        sql.append("usw_contrasenia, ");
        sql.append("usw_mail ");
        sql.append("FROM usuario_web ");

        try {
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql, null);

            while (rs.next()) {
                UsuarioWeb usuarioWeb = new UsuarioWeb();
                usuarioWeb.setUswCodigo(rs.getString("usw_codigo"));
                usuarioWeb.setUswNombre(rs.getString("usw_nombre"));
                usuarioWeb.setUswNombreUsuario(rs.getString("usw_nombre_usuario"));
                usuarioWeb.setUswContrasenia(rs.getString("usw_contrasenia"));
                usuarioWeb.setUswEmail(rs.getString("usw_mail"));

                usuarios.add(usuarioWeb);
            }
        } catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }

        return usuarios;
    }

    /**
     * Inserta en el sistema el usuario pasado por parametro, 
     * @param objeto UsuarioWeb.
     */
    public static void insertarUsuario(UsuarioWeb usuarioWeb) throws AvwException {
        StringBuilder sql = new StringBuilder();
        ArrayList params = new ArrayList();
        ConexionAvw conexion = new ConexionAvw();
        int pos =0;
        sql.append("INSERT INTO ");
        sql.append("usuario_web( ");
        sql.append("usw_nombre, ");
        sql.append("usw_nombre_usuario, ");
        sql.append("usw_contrasenia, ");
        sql.append("usw_mail) ");
        sql.append("VALUES( ?,?,?,?)");
        try{
            params.add(new BoundParam(++pos, usuarioWeb.getUswNombre(), VARCHAR));
            params.add(new BoundParam(++pos, usuarioWeb.getUswNombreUsuario(), VARCHAR));
            params.add(new BoundParam(++pos, usuarioWeb.getUswContrasenia(), VARCHAR, true));
            params.add(new BoundParam(++pos, usuarioWeb.getUswEmail(), VARCHAR));
            conexion.abrirConexion();
            conexion.executePreparedStatement(sql, params);
        }catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        }finally{
            conexion.cerrarConexion();
        }
    }

    /**
     * Modifica en el sistema el usuario con codigo pasado por parametro. 
     * @param objeto UsuarioWeb.
     */
    public static void modificarUsuario(UsuarioWeb usuarioWeb) throws AvwException {
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos =0;
        
        sql.append("UPDATE ");
        sql.append("usuario_web ");
        sql.append("SET ");
        sql.append(" usw_nombre = ?");
        sql.append(", usw_nombre_usuario = ?");
        sql.append(", usw_contrasenia = ?");
        sql.append(", usw_mail = ?");
        sql.append(" WHERE ");
        sql.append(" usw_codigo = ?");
        
        params.add(new BoundParam(++pos,usuarioWeb.getUswNombre(), VARCHAR));
        params.add(new BoundParam(++pos,usuarioWeb.getUswNombreUsuario(), VARCHAR));
        params.add(new BoundParam(++pos,usuarioWeb.getUswContrasenia(), VARCHAR));
        params.add(new BoundParam(++pos,usuarioWeb.getUswEmail(), VARCHAR));
        params.add(new BoundParam(++pos,usuarioWeb.getUswCodigo(), NUMERIC));
        logger.info(sql.toString());


        try {
            conexion.abrirConexion();
            conexion.executePreparedStatement(sql, params);
        } catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }
    }

    /**
     * Elimina del sistema al usuario pasado por parametro.
     * @param objeto UsuarioWeb (con solo el codigo).
     */
    public static void eliminarUsuario(UsuarioWeb usuarioWeb) throws AvwException {
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos =0;
        
        sql.append("DELETE FROM ");
        sql.append("usuario_web ");
        sql.append("WHERE ");
        sql.append(" usw_codigo = ?");
        params.add(new BoundParam(++pos, usuarioWeb.getUswCodigo(),NUMERIC));
        
        //Conexion.get().startTransaction();
        try {
            conexion.abrirConexion();
            conexion.executePreparedStatement(sql, params);
        } catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }
    }

    /**
     * Obtiene el usuario en base al codigo pasado por parametro
     * @param objeto UsuarioWeb (con solo el codigo).
     * @return objeto UsuarioWeb.
     */
    public static UsuarioWeb obtenerUsuario(UsuarioWeb usuarioWeb) throws AvwException {
        
        ResultSet rs;
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos =0;
        
        sql.append("SELECT ");
        sql.append("usw_codigo, ");
        sql.append("usw_nombre, ");
        sql.append("usw_nombre_usuario, ");
        sql.append("usw_contrasenia, ");
        sql.append("usw_mail ");
        sql.append("FROM usuario_web ");
        sql.append("WHERE usw_codigo = ? ");
        params.add(new BoundParam(++pos, usuarioWeb.getUswCodigo(), NUMERIC));
        
        try {
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql, params);

            rs.next();
            usuarioWeb.setUswNombre(rs.getString("usw_nombre"));
            usuarioWeb.setUswNombreUsuario(rs.getString("usw_nombre_usuario"));
            usuarioWeb.setUswContrasenia(rs.getString("usw_contrasenia"));
            usuarioWeb.setUswEmail(rs.getString("usw_mail"));

        } catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }

        return usuarioWeb;
    }

    /**
     * Verifica si existe el usuario en base al nombre pasado
     * por parametro.
     * @param objeto UsuarioWeb (con solo el nombre de usuario).
     * @throws  AvwException
     * @estado ??? Modificar, pq esta el mensaje de respueta en duro.
     */
    public static void  existeUsuarioPorNombreUsuario(UsuarioWeb usuarioWeb) throws AvwException {
        ResultSet rs;
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos =0;

        sql.append("SELECT ");
        sql.append("usw_codigo ");
        sql.append("FROM ");
        sql.append("usuario_web ");
        sql.append("WHERE ");
        sql.append("usw_nombre_usuario LIKE ? ");
        params.add(new BoundParam(++pos, usuarioWeb.getUswNombreUsuario(), VARCHAR));
        
        try {
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql, params);
            if (!rs.next()) // ???
                throw new AvwException("No existe usuario", true);

        } catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }
    }

    /**
     * Obtiene el UsuarioWeb en base al nombre de usuarioweb 
     * pasado por parametro.
     * @param objeto UsuarioWeb (con solo el nombre de usuario).
     * @return objeto UsuarioWeb o null en caso de que no exista.
     */
    public static UsuarioWeb obtenerUsuarioPorNombreUsuario(UsuarioWeb usuarioWeb) throws AvwException {
        ResultSet rs;
        StringBuilder sql = new StringBuilder();
        ConexionAvw conexion = new ConexionAvw();
        ArrayList params = new ArrayList();
        int pos =0;

        sql.append("SELECT ");
        sql.append("usw_codigo, ");
        sql.append("usw_nombre, ");
        sql.append("usw_nombre_usuario, ");
        sql.append("usw_contrasenia, ");
        sql.append("usw_mail ");
        sql.append("FROM ");
        sql.append("usuario_web ");
        sql.append("WHERE ");
        sql.append("usw_nombre_usuario LIKE ? ");
        params.add(new BoundParam(++pos,usuarioWeb.getUswNombreUsuario(), VARCHAR));

        try {
            logger.info("Obtener usuario: ");
            logger.info(sql.toString());
            
            conexion.abrirConexion();
            rs = conexion.getPreparedStatementResultSet(sql.toString(), params);
            if (rs.next()) {
                usuarioWeb.setUswCodigo(rs.getString("usw_codigo"));
                usuarioWeb.setUswNombre(rs.getString("usw_nombre"));
                usuarioWeb.setUswNombreUsuario(rs.getString("usw_nombre_usuario"));
                usuarioWeb.setUswContrasenia(rs.getString("usw_contrasenia"));
                usuarioWeb.setUswEmail(rs.getString("usw_mail"));

            } else {
                throw new AvwException("No existe usuario", true);
            }

        } catch (SQLException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw new AvwException(e);
        } finally {
            conexion.cerrarConexion();
        }

        return usuarioWeb;
    }
}
